home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
t_os
/
who
/
srchword.c
next >
Wrap
C/C++ Source or Header
|
1991-10-18
|
4KB
|
158 lines
/* srchword writen by GOOSE 1991.8.9
** 機能:
** 1ファイルに対し,複数のキーワードで検索し,キーワードを含む行を出力する。
** 呼び出し形式:
** srchword [-all] 検索対象ファイル名
** -allが指定されていると,必ずファイルの最後まで検索する。
** -allがない場合は,未一致のキーワードがなくなった時点で処理を終える。
** その他:
** キーワードは標準入力から与える。従って,ファイルから入力する場合は,
** srchword 検索対象ファイル名 < キーワードファイル名
** のようにリダイレクトする。
** なお,データ1行に対する文字列比較は,キーワードの1つが一致した時点で打ち
** 切ることに注意。
** 各キーワードは,次の何れかで区切ること。
** ・1つ以上の空白(半角,全角) or
** ・1つ以上の水平タブ or
** ・改行 or 終端文字
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define W0 (ONE_WORD *)0
#define ON 1
#define OFF 0
typedef struct ONE_WORD { /* キーワードリストの構造体 */
struct ONE_WORD *next;
short find; /* 一致行があったらON */
short len;
char word[1]; /* GCCなら要素0でもいいのに・・*/
} ONE_WORD;
/********** skipblank **********/
/* 文字列sのi番目以降の最初の空白(全角,半角,水平タブ)以外のオフセットを返す */
short skipblank(short *i, char *s)
{
for ( ;*(s+*i)!='\n' && *(s+*i)!='\0' ; (*i)++) {
if (*(s+*i)!=' ' && *(s+*i)!='\t' && memcmp(s+*i," ",2)!=0)
break;
if (memcmp(s+*i," ",2) == 0) (*i)++;
}
if ( *(s+*i) == '\n' ) *(s+*i) = '\0';
return(*i);
}
/********** skipchar **********/
/* 文字列sのi番目以降の次の文字のオフセットを返す.
** ・最初の空白(1byte,2byte),または
** ・水平タブまたは
** ・最初の指定された文字
** ALL文字列なら行末('\0')のオフセットを返す.
*/
short skipchar(short *i, char *s, char *c)
{
for ( ;*(s+*i)!='\n' && *(s+*i)!='\0' ; (*i)++) {
if (*(s+*i)==' ' || *(s+*i)=='\t' ||
*(s+*i)==*c||memcmp(s+*i," ",2)==0)
break;
}
if ( *(s+*i) == '\n' ) *(s+*i) = '\0';
return(*i);
}
/********** getoneword **********/
/* 文字列sのi番目以降から1単語を切り出し,ONE_WORD構造体にセットして返す */
ONE_WORD *getoneword(short *keyno,short *i, char *s)
{
short top,len;
ONE_WORD *ans;
top = skipblank(i, s); /* 先頭の空白を読み飛ばす */
if (*(s+top) == '\0') return(W0); /* レコードの終わりなら戻る */
len = skipchar(i,s,",")-top;
if ((ans=(ONE_WORD *)malloc(sizeof(ONE_WORD)+len)) == W0) {
fprintf(stderr,"memory not enough!\n");
exit(1);
}
ans->next = W0;
ans->find = OFF;
ans->len = len;
(*keyno)++;
memcpy(ans->word, s+top, len);
*(ans->word+len) = '\0';
return(ans);
}
/********** main(srchword) **********/
int main(argc, argv)
int argc;
char *argv[];
{
short pos,reccount,len,keyno,all;
FILE *fp;
ONE_WORD *topp,*wp;
char indata[256],buf[256],*file;
all = OFF;
topp = W0;
keyno = 0;
if (argc != 2 && argc!=3) {
fprintf(stderr,"usage: srchword [-all] filename < keyword_filename\n");
goto eend;
}
if (argc == 2)
file = argv[1];
else {
if (strcmp(argv[1],"-all") != 0) {
fprintf(stderr,"usage: srchword [-all] filename < keyword_filename\n");
goto eend;
}
all = ON;
file = argv[2];
}
/* キーワードを読み込んでメモリ上に展開する */
for (wp=(ONE_WORD *)&topp,pos=0; gets(indata)!=NULL ; pos=0)
for (; (wp->next=getoneword(&keyno,&pos,indata))!=W0; wp=wp->next);
/* 検索対象ファイルをオープン */
if ((fp=fopen(file,"r")) == NULL) {
fprintf(stderr, "file open error!\n");
goto eend;
}
/* 検索対象ファイルのレコードがある間繰り返し */
for (reccount=1,pos=0; fgets(indata,256,fp)!=NULL; reccount++,pos=0) {
for (skipblank(&pos,indata); indata[pos]!='\0'; pos++) {
len = strlen(indata+pos);
/* 切り出した1wordと全キーワードを比較 */
for (wp=topp; wp!=W0; wp=wp->next) {
if (len>=wp->len && memcmp(indata+pos,wp->word,wp->len)==0) {
printf("%d: %s",reccount,indata);
if (!all && wp->find == OFF) {
keyno--;
wp->find = ON;
if (keyno == 0) goto srchend;
}
goto nextrec;
}
}
}
nextrec:;
}
/* 後処理 */
srchend:;
fclose(fp);
for (wp=topp; wp!=W0; wp=topp) {
topp = wp->next;
free(wp);
}
exit(0);
eend:
exit(1);
}